package com.example.qxfw.hbqx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.qxfw.common.entity.qx.HeavyForecast;
import com.example.qxfw.common.entity.qx.YbzzForecastFinal;
import com.example.qxfw.common.entity.xt.SysConfig;
import com.example.qxfw.common.entity.zy.*;
import com.example.qxfw.hbqx.mapper.*;
import com.example.qxfw.hbqx.service.HjybcpService;
import com.example.qxfw.ybzz.mapper.EnviroStationMapper;
import com.example.qxfw.ybzz.mapper.SysConfigMapper;
import com.example.qxfw.ybzz.mapper.YbzzForecastFinalMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Properties;

@Service
public class HjybcpServiceImpl implements HjybcpService {
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private AirpolConFcstMapper airpolConFcstMapper;
    @Autowired
    private AirpolFcstMapper airpolFcstMapper;
    @Autowired
    private AirPolFcstFinalMapper airPolFcstFinalMapper;
    @Autowired
    private EnviroStationMapper enviroStationMapper;
    @Autowired
    private AirPollutionMapper airPollutionMapper;
    @Autowired
    private HeavyForecastMapper heavyForecastMapper;
    @Autowired
    private SumAtmosphericDayDataMapper sumAtmosphericDayDataMapper;
    @Autowired
    private YbzzForecastFinalMapper ybzzForecastFinalMapper;

    /**
     * 根据参数类型查询系统配置
     *
     * @param paramtype 参数类型
     * @return
     */
    @Override
    public List<SysConfig> selectByParamTypeOfSysConfig(String paramtype) {
        return sysConfigMapper.selectList(new LambdaQueryWrapper<SysConfig>()
                .like(StringUtils.isNotBlank(paramtype), SysConfig::getParamtype, paramtype));
    }

    /**
     * 根据观测时间段查询污染扩散等级预报
     *
     * @param observtimeStart 观测时间起点
     * @param observtimeEnd   观测时间终点
     * @return
     */
    @Override
    public List<AirpolConFcst> selectByObservTimeOfAirpolConFcst(Date observtimeStart, Date observtimeEnd) {
        return airpolConFcstMapper.selectByObservTimeOfAirpolConFcst(observtimeStart, observtimeEnd);
    }

    /**
     * 根据观测时间更新污染扩散等级预报
     *
     * @param observtime  观测时间
     * @param level       等级
     * @param totalweight 总权重
     * @param asseaa      评价
     * @param describe    描述
     * @param condition   条件
     * @return
     */
    @Override
    public int updateByObservTime(Date observtime, String level, Integer totalweight, String asseaa, String describe, String condition) {
        return airpolConFcstMapper.updateByObservTime(observtime, level, totalweight, asseaa, describe, condition);
    }

    /**
     * 插入数据到污染扩散等级预报
     *
     * @param observtime  观测时间
     * @param level       等级
     * @param totalweight 总权重
     * @param asseaa      评价
     * @param describe    描述
     * @param condition   条件
     * @return
     */
    @Override
    public int insertOfAirPolConForecast(Date observtime, String level, Integer totalweight, String asseaa, String describe, String condition) {
        return airpolConFcstMapper.insertOfAirPolConForecast(observtime, level, totalweight, asseaa, describe, condition);
    }

    /**
     * 根据名字和类型修改参数赋值
     *
     * @param paramvalue
     * @param paramname
     * @param paramtype
     * @return
     */
    @Override
    public int updateByNameAndTypeOfSysConfig(String paramvalue, String paramname, String paramtype) {
        return sysConfigMapper.updateByNameAndTypeOfSysConfig(paramvalue, paramname, paramtype);
    }

    /**
     * 根据日期类型id删除空气质量精细化预报主表数据
     *
     * @param datechar     日期
     * @param forecasttype 预报类型
     * @param stationid    站点序号
     * @return
     */
    @Override
    public int deleteByDateTypeIdOfAirpolFcst(Date datechar, Integer forecasttype, String stationid) {
        return airpolFcstMapper.delete(new LambdaQueryWrapper<AirpolFcst>()
                .eq(datechar != null, AirpolFcst::getDatechar, datechar)
                .eq(forecasttype != null, AirpolFcst::getForecasttype, forecasttype)
                .eq(StringUtils.isNotBlank(stationid), AirpolFcst::getStationid, stationid));

    }

    /**
     * 添加空气质量精细化预报结果表
     *
     * @param stationid
     * @param stationname
     * @param datechar
     * @param forecasttype
     * @param ntimes
     * @param so2
     * @param no2
     * @param pm10
     * @param co
     * @param o3_1h
     * @param o3_8h
     * @param pm2_5
     * @param pri
     * @param aqi
     * @param longitude
     * @param latitude
     * @param altitude
     * @return
     */
    @Override
    public int insertOfAirPolFcstFinal(
            String stationid, String stationname,
            Date datechar, Integer forecasttype, Integer ntimes,
            Double so2, Double no2, Double pm10, Double co,
            Double o3_1h, Double o3_8h, Double pm2_5, String pri,
            Integer aqi, Double longitude, Double latitude, Double altitude) {
        return airPolFcstFinalMapper.insertOfAirPolFcstFinal(
                stationid, stationname, datechar, forecasttype, ntimes, so2, no2, pm10,
                co, o3_1h, o3_8h, pm2_5, pri, aqi, longitude, latitude, altitude
        );
    }

    /**
     * 根据日期和预报类型查询空气质量精细化预报主表
     *
     * @param datechar     日期
     * @param forecasttype 预报类型
     * @return
     */
    @Override
    public List<AirpolFcst> selectByDateAndTypeOfAirpolFcst(Date datechar, Integer forecasttype) {
        return airpolFcstMapper.selectList(new LambdaQueryWrapper<AirpolFcst>()
                .eq(datechar != null, AirpolFcst::getDatechar, datechar)
                .eq(forecasttype != null, AirpolFcst::getForecasttype, forecasttype));
    }

    /**
     * 查询所有环保站信息
     *
     * @return
     */
    @Override
    public List<EnviroStation> selectOfEnviroStation() {
        return enviroStationMapper.selectList(new LambdaQueryWrapper());
    }

    /**
     * 根据站点id日期预报类型查询空气质量精细化预报主表
     *
     * @param stationid     站点id
     * @param datecharStart 开始日期
     * @param datecharEnd   结束日期
     * @param forecasttype  预报类型
     * @return
     */
    @Override
    public List<AirpolFcst> selectByIdDateTypeOfAirpolFcst(String stationid, Date datecharStart, Date datecharEnd, Integer forecasttype) {
        return airpolFcstMapper.selectList(new LambdaQueryWrapper<AirpolFcst>()
                .eq(StringUtils.isNotBlank(stationid), AirpolFcst::getStationid, stationid)
                .eq(forecasttype != null, AirpolFcst::getForecasttype, forecasttype)
                .between(AirpolFcst::getDatechar, datecharStart, datecharEnd));
    }

    /**
     * 根据日期查询空气质量精细化预报主表,不包含站点id的
     *
     * @param stationid       站点id
     * @param observtimeStart 开始日期
     * @param observtimeEnd   结束日期
     * @return
     */
    @Override
    public List<AirPollution> selectByNotIdAndDateOfAirpolFcst(String stationid, Date observtimeStart, Date observtimeEnd) {
        return airPollutionMapper.selectList(new LambdaQueryWrapper<AirPollution>()
                .between(AirPollution::getObservtime, observtimeStart, observtimeEnd)
                .notLike(StringUtils.isNotBlank(stationid), AirPollution::getStationid, stationid));


    }

    /**
     * 根据站点id日期预报类型查询空气质量精细化预报结果表
     *
     * @param stationid     站点id
     * @param datecharStart 开始日期
     * @param datecharEnd   结束日期
     * @param forecasttype  预报类型
     * @return
     */
    @Override
    public List<AirPolFcstFinal> selectByIdDateTypeOfAirPolFcstFinal(String stationid, Date datecharStart, Date datecharEnd, Integer forecasttype) {
        return airPolFcstFinalMapper.selectList(new LambdaQueryWrapper<AirPolFcstFinal>()
                .eq(StringUtils.isNotBlank(stationid), AirPolFcstFinal::getStationid, stationid)
                .eq(forecasttype != null, AirPolFcstFinal::getForecasttype, forecasttype)
                .between(AirPolFcstFinal::getDatechar, datecharStart, datecharEnd));
    }

    /**
     * 根据日期查询空气质量精细化预报主表,转换
     *
     * @param stationid       站点id
     * @param observtimeStart 开始日期
     * @param observtimeEnd   结束日期
     * @return
     */
    @Override
    public List<AirPollution> selectByNotIdAndDateOfAirpolFcstChange(String stationid, Date observtimeStart, Date observtimeEnd) {
        return airPollutionMapper.selectList(Wrappers.<AirPollution>query()
                .select("distinct StationID", "StationName",
                        "to_char((cast(observtime as timestamp) %2b CAST(Ntimes||'hour' as INTERVAL)),'yyyy-MM-dd hh:mm:ss') as DateChar",
                        "case when ConcenSO2 is Null then 0 else ConcenSO2 end as ConcenSO2",
                        "case when ConcenNO2 is Null then 0 else ConcenNO2 end as ConcenNO2",
                        "case when ConcenPM10 is Null then 0 else ConcenPM10 end as ConcenPM10",
                        "case when ConcenCO is Null then 0 else ConcenCO end as ConcenCO",
                        "case when ConcenO3 is Null then 0 else ConcenO3 end as ConcenO3",
                        "case when ConcenO38H is Null then 0 else ConcenO38H end as ConcenO38H",
                        "case when ConcenPM2p5 is Null then 0 else ConcenPM2p5 end as ConcenPM2p5",
                        "case when AQI is Null then 0 else AQI end as AQI",
                        "to_char(observtime,'hh') as firstpollution")
                .lambda()
                .between(AirPollution::getObservtime, observtimeStart, observtimeEnd)
                .eq(AirPollution::getStationid, stationid)
                .groupBy(AirPollution::getStationid));
    }

    /**
     * 根据当前时间和判定调价查询数据库是否有数据
     *
     * @param heavyForecast 重要污染预报
     * @return
     */
    @Override
    public List<HeavyForecast> selectByNowTimeAndjudgetypeOfHeavyForecast(HeavyForecast heavyForecast) {
        return heavyForecastMapper.selectList(new LambdaQueryWrapper<HeavyForecast>()
                .eq(HeavyForecast::getTime, heavyForecast.getTime())
                .eq(HeavyForecast::getJudgetype, heavyForecast.getJudgetype()));
    }

    /**
     * 更新重要污染预报
     *
     * @param heavyForecast 重要污染预报
     * @return
     */
    @Override
    public int updateOfHeavyForecast(HeavyForecast heavyForecast) {
        return heavyForecastMapper.update(heavyForecast, new LambdaQueryWrapper<HeavyForecast>()
                .eq(HeavyForecast::getJudgetype, heavyForecast.getJudgetype())
                .eq(HeavyForecast::getTime, heavyForecast.getTime()));
    }

    /**
     * 添加重要污染预报
     *
     * @param heavyForecast 重要污染预报
     * @return
     */
    @Override
    public int insertOfHeavyForecast(HeavyForecast heavyForecast) {
        return heavyForecastMapper.insert(heavyForecast);
    }

    @Override
    public List<AirpolFcst> selectByDateAndTimeAndTypeOfAirpolFcst(Timestamp datechar, Integer forecasttype) {
        return airpolFcstMapper.selectList(new LambdaQueryWrapper<AirpolFcst>()
        .eq(datechar != null, AirpolFcst::getDatechar, datechar)
        .eq(forecasttype != 0, AirpolFcst::getForecasttype, forecasttype));
    }


//--------------------------------------------------模型-----------------------------------------------------------------


    /**
     * 自动判断（AQI模型）
     */
    @Override
    public void AutoJudge() {
        Double a = 0.0;
        Double x1 = 0.0;     //x1--前日AQI值（前24小时值取平均）
        Double x3 = 0.0;     //x3--14时气温
        Double x4 = 0.0;     //x4--日均相对湿度
        Double x5 = 0.0;     //x5--08时相对湿度
        Double x6 = 0.0;     //x6--日最小相对湿度
        Double x7 = 0.0;     //x7--日平均气压
        Double x9 = 0.0;     //x9--降水时长
        Double x10 = 0.0;    //x10--连续无降水日数
        Double x11 = 0.0;    //x11--日最大风速
        Double x12 = 0.0;    //x12--日均10分钟风速
        Double x13 = 0.0;    //x13--14时风速
        Double x17 = 0.0;    //x17--日照时数

        String avgTemp = "0";     //日均气温
        String avgHumid = "0";    //日均相对湿度
        String minHumid = "0";    //日最小湿度
        String rain = "0";        //日降水量
        String maxWind = "0";     //日最大风速
        String avgWind = "0";     //日均10分钟风速

        String temp14 = "0";      //14时气温
        String humid14 = "0";     //14时相对湿度
        String wind14 = "0";      //14时风速
        String humid08 = "0";     //08时相对湿度
        Integer rainH = 0;        //降水时长
        Integer noRainDay = 0;    //连续无降水日
        Integer sunNum = 0;       //日照时数

        Integer forcastType = 1;  //天气类型

        //创建一个Properties对象，并通过FileInputStream加载配置文件[ config.properties ]--->根据情况修改
        //使用getProperty方法来获取指定配置项的值。
        Properties properties = new Properties();
        try {
            FileInputStream fileInputStream = new FileInputStream("config.properties");
            properties.load(fileInputStream);
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String strCityID = properties.getProperty("strCityID");//城市ID
        Date time = new Date();//当前时间
        String stationId = "";//站点id
        List<SumAtmosphericDayData> list = sumAtmosphericDayDataMapper
                .selectByTimeAndIdOfSumAtmosphericDayData(time, stationId);

        if (list.size()>0){
            x1 = Double.parseDouble(String.valueOf(list.get(0).getAqi()));
        }

        /**气象数据*/
        List<YbzzForecastFinal> ybzzForecastFinalList =
                ybzzForecastFinalMapper.selectByDateAndTypeAndIdOfYbzzForecastFinal(time, forcastType, stationId);

        if (ybzzForecastFinalList != null && !ybzzForecastFinalList.isEmpty()) {
            YbzzForecastFinal forecastfinal = ybzzForecastFinalList.get(0);

            String strTemp = String.valueOf(forecastfinal.getTemperature());
            String strHumid = String.valueOf(forecastfinal.getHumid());
            String strMinHumid = String.valueOf(forecastfinal.getMinhumid());
            String strRain = String.valueOf(forecastfinal.getRain());
            String strMaxWind = String.valueOf(forecastfinal.getWind());
            String stravgWind = String.valueOf(forecastfinal.getWindd());

            // 判断字段是否有效并赋值给对应的变量
            if (strTemp != null && !strTemp.equals("-65535")) {
                avgTemp = strTemp.trim();
            }
            if (strHumid != null && !strHumid.equals("-65535")) {
                avgHumid = strHumid.trim();
            }
            if (strMinHumid != null && !strMinHumid.equals("-65535")) {
                minHumid = strMinHumid.trim();
            }
            if (strRain != null && !strRain.equals("-65535")) {
                rain = strRain.trim();
            }
            if (strMaxWind != null && !strMaxWind.equals("-65535")) {
                maxWind = strMaxWind.trim();
            }
            if (stravgWind != null && !stravgWind.equals("-65535")) {
                avgWind = stravgWind.trim();
            }
        }
        /**时数据*/
        Integer ntimes1 = 14;//后期修改值
        List<YbzzForecastFinal> listc =
                ybzzForecastFinalMapper.selectByDateAndTypeAndIdAndNTimesOfYbzzForecastFinal(
                time, forcastType, strCityID, ntimes1);
        Integer ntimes2 = 8;//后期修改值
        List<YbzzForecastFinal> listz =
                ybzzForecastFinalMapper.selectByDateAndTypeAndIdAndNTimesOfYbzzForecastFinal(
                        time, forcastType, strCityID, ntimes2);

        if (listc.size() > 0 && listz.size() > 0) {

            float temperatureValue = listc.get(0).getTemperature();
            String strTemp14 = String.valueOf(temperatureValue).trim();

            float windValue = listc.get(0).getWind();
            String strWind14 = String.valueOf(windValue).trim();

            float humidValue = listc.get(0).getHumid();
            String strHumid14 = String.valueOf(humidValue).trim();

            float humid08Value = listz.get(0).getHumid();
            String strHumid08 = String.valueOf(humid08Value).trim();


            if (!strTemp14.isEmpty() && !"-65535".equals(strTemp14)) {
                temp14 = strTemp14;
            }

            if (!strWind14.isEmpty() && !"-65535".equals(strWind14)) {
                wind14 = strWind14;
            }

            if (!strHumid14.isEmpty() && !"-65535".equals(strHumid14)) {
                humid14 = strHumid14;
            }

            if (!strHumid08.isEmpty() && !"-65535".equals(strHumid08)) {
                humid08 = strHumid08;
            }
        }
        /**降水时长*/

        Date dateChar = new Date();
        Integer forecastType = 1;
        String stationID = "";
        List<YbzzForecastFinal> listd = ybzzForecastFinalMapper
                .selectList(new LambdaQueryWrapper<YbzzForecastFinal>()
                        .eq(YbzzForecastFinal::getDatechar, dateChar)
                        .eq(YbzzForecastFinal::getForecasttype, forecastType)
                        .eq(YbzzForecastFinal::getStationid, stationID)
                        .gt(YbzzForecastFinal::getRain, 0));

    }

}

